package net.kehuilai.handler;

import com.alibaba.fastjson.JSON;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import net.kehuilai.model.BaseMessage;
import net.kehuilai.util.StringTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Created by genghz on 16/12/5.
 */
@ChannelHandler.Sharable
public class ServerHandler extends ChannelInboundHandlerAdapter {

    private static final Logger log = LoggerFactory.getLogger(ClientHandler.class);

    private final ConcurrentMap<String, Channel> clientMap = new ConcurrentHashMap<String, Channel>();

    // channnel connect
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        this.clientMap.put(channel.id().asLongText(), channel);
        log.info("[socket_server] client connect: {}", channel.id().asLongText());
    }

    // channnel close
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        this.clientMap.remove(channel.id().asLongText());
        log.info("[socket_server] client disconnect: {}", channel.id().asLongText());
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        BaseMessage message = (BaseMessage) msg;
        // 获取sessionId
        String msgId = message.getId();

        if (StringTool.isEmpty(msgId)) {
            // 接收并打印客户端的信息
            System.out.println("id: " + ctx.channel().id().asLongText() + ", msg: " + JSON.toJSONString(message));
        } else {
            message.setData("server response");
            ctx.writeAndFlush(message);
            System.out.println("id: " + ctx.channel().id().asLongText() + ", msg: " + JSON.toJSONString(message));
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    public Channel getClient(String clientId) {
        return this.clientMap.get(clientId);
    }
}
